Skip to content

fix: keep delivering inverse search past an unreachable server - #3301

Merged
lervag merged 1 commit into
lervag:masterfrom
Chiarandini:fix-inverse-search-stale-socket
Sep 4, 2026
Merged

fix: keep delivering inverse search past an unreachable server#3301
lervag merged 1 commit into
lervag:masterfrom
Chiarandini:fix-inverse-search-stale-socket

Conversation

@Chiarandini

Copy link
Copy Markdown
Contributor

In s:inverse_search_cmd_nvim, the try/catch covers sockconnect() but not the rpcnotify() and chanclose() that follow:

for l:server in readfile(s:nvim_servernames)
  try
    let l:socket = sockconnect("pipe", l:server, {"rpc": 1})
  catch
  endtry

  call rpcnotify(l:socket, ...)
  call chanclose(l:socket)
endfor

When a server in the log is no longer reachable, the catch swallows the connection failure and l:socket is then either undefined, raising E121, or still holding the previous iteration's closed channel. Either way the error leaves the loop and is caught by the outer try in inverse_search_cmd(), so delivery stops at the first unreachable server and every server listed after it is skipped.

s:nvim_prune_servernames() keeps the log tidy, but it only runs from vimtex#view#init_buffer(), so an instance that exits between prunes leaves exactly this state: one dead entry in the log, and inverse search silently doing nothing in every still-running instance registered after it.

Reproducing

  1. Open a tex file in Neovim instance A, then another in instance B.
  2. Quit A with kill -9 so its socket is not pruned from the log.
  3. Without opening a new tex buffer anywhere (which would prune), inverse-search from the PDF viewer into the document open in B.
  4. Nothing happens. With this change, B receives the jump.

The change

One continue in the catch, which skips a server that cannot be connected and leaves the rest of the loop to run. This matches the shape s:nvim_prune_servernames() already uses twenty lines below, where add() and chanclose() are inside the try.

No test is included: the failure needs two Neovim instances and a socket that dies between prunes, which I could not express in the existing test/ harness. Happy to add one if you can point me at the right pattern.

The try/catch around sockconnect() does not cover the rpcnotify() and
chanclose() that follow it. When a server in the log is gone, the catch
swallows the connection failure and l:socket is then either undefined,
raising E121, or still holds the previous iteration's closed channel.

Either way the error leaves the loop and is caught by the outer try in
inverse_search_cmd(), so delivery stops at the first unreachable server and
every server listed after it is skipped.

s:nvim_prune_servernames() keeps the log tidy, but it only runs when a tex
buffer initialises, so an instance that exits between prunes leaves exactly
this state: one dead entry, and inverse search silently doing nothing in
every still-running instance registered after it.

The pruning function twenty lines below already uses the correct shape, with
its add() and chanclose() inside the try.
@lervag

lervag commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants